#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <netinet/in.h>
#include <resolv.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

//#define SCENARIO_1
//#define SCENARIO_2
#define SCENARIO_3

#define BUFFERLEN		5024
#define BIGBUFFERLEN	1000000

int main(int argv, char** argc){


    int host_port= 3128;
    char* host_name="127.0.0.1";



    struct sockaddr_in my_addr;

    char buffer[BUFFERLEN];
    char bigbuffer[BIGBUFFERLEN];
	int bytecount;
    int buffer_len=0;
	int bigbuffer_len=0;

    int hsock;
    int * p_int;
    int err;

	//Boiler plate stuff

    hsock = socket(AF_INET, SOCK_STREAM, 0);
    if(hsock == -1){
        printf("Error initializing socket %d\n",errno);
        goto FINISH;
    }
    
    p_int = (int*)malloc(sizeof(int));
    *p_int = 1;
        
    if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1 )||
        (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int)) == -1 ) ){
        printf("Error setting options %d\n",errno);
        free(p_int);
        goto FINISH;
    }
    free(p_int);

    my_addr.sin_family = AF_INET ;
    my_addr.sin_port = htons(host_port);
    
    memset(&(my_addr.sin_zero), 0, 8);
    my_addr.sin_addr.s_addr = inet_addr(host_name);

    if( connect( hsock, (struct sockaddr*)&my_addr, sizeof(my_addr)) == -1 ){
        if((err = errno) != EINPROGRESS){
            fprintf(stderr, "Error connecting socket %d\n", errno);
            goto FINISH;
        }
    }
	//End of boiler plate stuff


/****************************************************************
 * Scenario 1: The client opens the socked connects to the server
 * via speedbump, but is not ready to read. What used to happen 
 * was that speedbump would continue to read, and as it couldn't
 * write, the buffers would grow. Th fix is to stop reading after
 * a certain amount and wait to write.
 ***************************************************************/
#ifdef SCENARIO_1
    buffer_len = BUFFERLEN;
    memset(buffer, '\0', buffer_len);

    sprintf(buffer, "GET /php/b/learning.zip HTTP/1.1\r\nX-Via: ninja\r\nX-Forwarded-For: 123.334.334.334\r\nHost: 127.0.0.1\r\n\r\n\r\n");
	printf("%s\n---------------------------------------\n", buffer);
	int totalbytes=0;
    if( (bytecount=send(hsock, buffer, strlen(buffer),0))== -1){
        fprintf(stderr, "Error sending data %d\n", errno);
        goto FINISH;
    }
    printf("Sent bytes %d\n", bytecount);
	sleep(5);
	int count=0;
    while((bytecount = recv(hsock, buffer, buffer_len, 0)) > 0){
		totalbytes+=bytecount;
		if(count++ > 100 ){
			count=0;
			printf("sleeeping\n");
			sleep(3);
		}
		printf("Recieved bytes %d total %d\n", bytecount, totalbytes);
	}
    if(bytecount<0)
		perror("gansied\n");

#endif



/****************************************************************
 * Scenario 2: Keep sending rubbish to the socket without a 
 * proper header. Speedbump has to quit after a certain amount of
 * bytes have been read, and no header decoded.
 ***************************************************************/
#ifdef SCENARIO_2
    bigbuffer_len = BIGBUFFERLEN;
    memset(bigbuffer, 'g', bigbuffer_len);

    //sprintf(bigbuffer, "GET /php/b/learning.zip HTTP/1.1\r\nX-Via: ninja\r\nX-Forwarded-For: 123.334.334.334\r\nHost: 127.0.0.1\r\n\r\n");
	//printf("%s\n---------------------------------------\n", buffer);
	int totalbytes=0;
    if( (bytecount=send(hsock, bigbuffer, bigbuffer_len,0))== -1){
        fprintf(stderr, "Error sending data %d\n", errno);
        goto FINISH;
    }
    printf("Sent bytes %d\n", bytecount);
	sleep(5);
	int count=0;
    while((bytecount = recv(hsock, buffer, buffer_len, 0)) > 0){
		totalbytes+=bytecount;
		if(count++ > 100 ){
			count=0;
			printf("sleeeping\n");
			sleep(3);
		}
		printf("Recieved bytes %d total %d\n", bytecount, totalbytes);
	}
    if(bytecount<0)
		perror("gansied\n");

#endif



/****************************************************************
 * Scenario 2: Keep sending rubbish to the socket without a 
 * proper header. Speedbump has to quit after a certain amount of
 * bytes have been read, and no header decoded.
 ***************************************************************/
#ifdef SCENARIO_3
    printf("%s\n---------------- SCENARIO 3 -------------------\n", buffer);
	buffer_len = BUFFERLEN;
    memset(buffer, '\0', buffer_len);

    //sprintf(buffer, "GET / \r\ntest: hello\r\nninja:\r\nx:xman\r\n\r\n\r\n\r\n");
	sprintf(buffer, "\r\n\r\nfdfdfdfd\r\n\r\ndffdfdfd");

	int totalbytes=0;
    if( (bytecount=send(hsock, buffer, strlen(buffer),0))== -1){
        fprintf(stderr, "Error sending data %d\n", errno);
        goto FINISH;
    }
    printf("Sent bytes %d\n", bytecount);
	sleep(5);
	int count=0;
    while((bytecount = recv(hsock, buffer, buffer_len, 0)) > 0){
		totalbytes+=bytecount;
		if(count++ > 100 ){
			count=0;
			printf("sleeeping\n");
			sleep(3);
		}
		printf("Recieved bytes %d total %d\n", bytecount, totalbytes);
	}
    if(bytecount<0)
		perror("gansied\n");
#endif








	printf("finished\n");
    close(hsock);
    
FINISH:
;
}